import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Button, DatePicker, Form, Select, Spin, Table, Tag, Tooltip, message } from 'antd';
import { isNil, omitBy } from 'lodash';
import moment from 'moment';
import classNames from 'classnames';
import { connect } from 'umi';

import { SearchInput } from '@/components/UserForm';
import Pagination from '@/components/Pagination';
import OrganizationSelect from '@/components/OrganizationSelect';
import { isSuccess } from '@/utils/request';
import AuthComponent from '@/utils/auth/AuthComponent';

import BaseSettingProvider from '@/pages/SalaryManage/components/BaseSettingProvider';
import EmptyPlaceHolder from '@/pages/SalaryManage/components/EmptyPlaceHolder';
import { getReadableNameByCode } from '@/pages/SalaryManage/components/CityCascader';
import { insuranceHousingFundService } from '@/services/salaryManage/salaryCalculateService';
import Search from '@/pages/SalaryManage/components/SuperSearch';
import TwoColHead from '@/pages/SalaryManage/components/TwoColHead';
import { queryEmployeeList } from '@/services/salaryManage/salaryCommon';
import { amountSettingColumn, commonColumn, dateColumn, yearMonthColumn } from '@/pages/SalaryManage/utils/TableUtil';
import { NumberSettingFormatter } from '@/pages/SalaryManage/components/NumberFormatter';
import EmployeeNameWrapper from '@/pages/SalaryManage/components/EmployeeNameWrapper';
import { goToMedicalSocialSecurity } from '@/pages/SalaryManage/utils/pageNavigateUtil';
import { addMinusStatusEnum, housePlaceEnum, jobStatusEnum } from '@/pages/SalaryManage/enum';
import InsuranceFundFileMenuFilter from '@/pages/SalaryManage/SalaryCalculate/InsuranceFundFile/components/InsuranceFundFileMenuFilter';
import InsuranceFundFileRouter from '@/pages/SalaryManage/SalaryCalculate/InsuranceFundFile/components/InsuranceFundFileRouter';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import SalaryConfigTipPage from '@/pages/SalaryManage/components/SalaryConfigTipPage';
import salaryStyle from '@/pages/SalaryManage/salaryManage.less';

const namespace = 'insuranceFundFileModel';
const addMinusStatusEnumList = addMinusStatusEnum.list();
const jobStatusEnumList = jobStatusEnum.list();

const { Option } = Select;
const { RangePicker } = DatePicker;

const currentMonth = moment().format('YYYY-MM');

// e.g. 20101003 => 2010-10
const getYearMonth = date => (date ? moment(date).format('YYYY-MM') : null);

const tipRender = (showValue, tipValue) => {
    let tip = null;

    if (showValue && tipValue && +showValue !== +tipValue && +tipValue > 0) {
        const title = (
            <>
                标准险金：
                <NumberSettingFormatter value={tipValue} />
            </>
        );
        tip = (
            <Tooltip title={title} placement="bottomLeft">
                <i className="color-tag" />
            </Tooltip>
        );
    }

    return (
        <>
            {tip}
            <div>
                <NumberSettingFormatter value={showValue} />
            </div>
        </>
    );
};

const tableColumns = [
    {
        title: (
            <EmployeeNameWrapper
                left={<i className={classNames(salaryStyle.circle, salaryStyle.circleHidden)} />}
                name="姓名"
            />
        ),
        dataIndex: 'name',
        align: 'left',
        fixed: true,
        width: 202,
        render(text, record) {
            let tag = null;
            let circle = <i className={classNames(salaryStyle.circle, salaryStyle.circleHidden)} />;
            // 入职日期与系统日期同一天时
            if (getYearMonth(record.startDate) === currentMonth) {
                circle = <i className={salaryStyle.circle} />;
                tag = (
                    <Tag color="orange" className={classNames(salaryStyle.noBorderTag, salaryStyle.mr0)}>
                        入职
                    </Tag>
                );
            }

            if (getYearMonth(record.endDate) === currentMonth) {
                circle = <i className={salaryStyle.circle} />;
                tag = (
                    <Tag color="red" className={classNames(salaryStyle.noBorderTag, salaryStyle.mr0)}>
                        离职
                    </Tag>
                );
            }

            return <EmployeeNameWrapper left={circle} name={text} right={tag} />;
        },
        ellipsis: true
    },
    commonColumn({
        title: '工号',
        dataIndex: 'employeeNo',
        align: 'center',
        fixed: true,
        width: 100,
        ellipsis: true
    }),
    commonColumn({
        title: '证件号',
        dataIndex: 'cardNo',
        align: 'center',
        width: 200,
        ellipsis: true
    }),
    dateColumn({
        title: '入职日期',
        dataIndex: 'startDate',
        ellipsis: true
    }),
    dateColumn({
        title: '离职日期',
        dataIndex: 'endDate',
        ellipsis: true
    }),
    {
        title: '状态',
        dataIndex: 'status',
        align: 'center',
        width: 110,
        render(text) {
            return text ? jobStatusEnum.getShowName(text) : <EmptyPlaceHolder />;
        },
        ellipsis: true
    },
    commonColumn({
        title: '组织机构',
        dataIndex: 'departmentName',
        width: 200,
        ellipsis: true
    }),
    amountSettingColumn({
        title: '初始月薪',
        dataIndex: 'encryptBaseSalaryAmt',
        ellipsis: true
    }),
    amountSettingColumn({
        title: '初始月绩效',
        dataIndex: 'encryptKpiMonthAmt',
        ellipsis: true
    }),
    {
        title: '社保方案',
        dataIndex: 'housePlace',
        width: 200,
        render(text, record) {
            const result = [];

            if (record.socialCityCode) {
                result.push(getReadableNameByCode(record.socialCityCode));
            }

            if (text) {
                result.push(housePlaceEnum.getShowName(text));
            }

            return result.length === 0 ? <EmptyPlaceHolder /> : result.join('-');
        },
        ellipsis: true
    },
    yearMonthColumn({
        title: '起始缴交月',
        dataIndex: 'socialStart',
        render(text, record) {
            const { socialStartYear: year, socialStartMonth: month } = record;
            return year && month ? moment(year * 100 + month, 'YYYYMM').format('YYYY-MM') : <EmptyPlaceHolder />;
        },
        ellipsis: true
    }),
    yearMonthColumn({
        title: '最后缴交月',
        dataIndex: 'socialEndYear',
        render(text, record) {
            const { socialEndYear: year, socialEndMonth: month } = record;
            return year && month ? moment(year * 100 + month, 'YYYYMM').format('YYYY-MM') : <EmptyPlaceHolder />;
        },
        ellipsis: true
    }),
    {
        title: '险金基数（个人）',
        dataIndex: 'xjjs',
        children: [
            amountSettingColumn({
                title: '养老保险',
                dataIndex: 'encryptOldBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectOldBaseAmt);
                },
                ellipsis: true
            }),
            amountSettingColumn({
                title: '失业保险',
                dataIndex: 'encryptUnemployBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectUnemployBaseAmt);
                },
                ellipsis: true
            }),
            amountSettingColumn({
                title: '医疗保险',
                dataIndex: 'encryptHospitalBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectHospitalBaseAmt);
                },
                ellipsis: true
            }),
            amountSettingColumn({
                title: '生育保险',
                dataIndex: 'encryptBirthBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectBirthBaseAmt);
                },
                ellipsis: true
            }),
            amountSettingColumn({
                title: '工伤保险',
                dataIndex: 'encryptHarmBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectHarmBaseAmt);
                },
                ellipsis: true
            }),
            amountSettingColumn({
                title: '大病保险',
                dataIndex: 'encryptIllBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectIllBaseAmt);
                },
                ellipsis: true
            }),
            amountSettingColumn({
                title: '公积金',
                dataIndex: 'encryptFundBaseAmt',
                className: salaryStyle.colorTagCell,
                render(text, record) {
                    return tipRender(text, record.encryptUnEffectFundBaseAmt);
                },
                ellipsis: true
            })
        ]
    },
    {
        title: '增减员状态',
        dataIndex: 'socialStatus',
        align: 'center',
        width: 100,
        render(text) {
            return text ? addMinusStatusEnum.getShowName(text) : <EmptyPlaceHolder />;
        },
        ellipsis: true
    }
];

const SearchWrapper = ({ form, onSearch, organizationCode, wrapperFormRef }) => {
    const { getFieldDecorator } = form;

    useEffect(() => {
        if (wrapperFormRef) {
            wrapperFormRef(form);
        }
    }, [wrapperFormRef]);

    return (
        <Search.Wrapper onSearch={onSearch}>
            <TwoColHead
                left={
                    <Search.Commonly>
                        <Search.Item label="增减员状态">
                            {getFieldDecorator('socialStatus', { initialValue: addMinusStatusEnumList[0].value })(
                                <Select style={{ width: '8.571em' }}>
                                    {addMinusStatusEnumList.map(status => (
                                        <Option key={status.value} value={status.value}>
                                            {addMinusStatusEnum.getShowName(status.value)}
                                        </Option>
                                    ))}
                                </Select>
                            )}
                        </Search.Item>
                    </Search.Commonly>
                }
                right={
                    <React.Fragment>
                        <AuthComponent code="finance:salary:computation:social:social:archive">
                            <Button type="primary" ghost onClick={() => goToMedicalSocialSecurity(organizationCode)}>
                                险金档案
                            </Button>
                        </AuthComponent>
                        {/*
                        <Tooltip title="自定义表头">
                            <Button className={salaryStyle.squareIconBtn}>
                                <span className="iconfont iconsearchbar_modifyheader_icon_default" />
                            </Button>
                        </Tooltip>
                        <Tooltip title="地税同步">
                            <Button className={salaryStyle.squareIconBtn}>
                                <span className="iconfont iconzhuangtaibiangeng" />
                            </Button>
                        </Tooltip>
                        */}
                    </React.Fragment>
                }
            />
            <Search.More>
                <Search.Item label="姓名">
                    <span>
                        {getFieldDecorator('v_employeeCode')(
                            <SearchInput
                                params={{
                                    organizationCode
                                }}
                                getData={async params => {
                                    if (!params.organizationCode) {
                                        return [];
                                    }
                                    const employeeResponse = await queryEmployeeList({
                                        organizationCode: params.organizationCode
                                    });
                                    return isSuccess(employeeResponse) ? employeeResponse.data || [] : [];
                                }}
                                selectProps={{
                                    placeholder: '请输入员工姓名',
                                    allowClear: true
                                }}
                                fieldsName={{
                                    value: 'employeeCode',
                                    title: 'name'
                                }}
                                style={{ width: '12.875em' }}
                            />
                        )}
                    </span>
                </Search.Item>

                <Search.Item label="入职日期">
                    {getFieldDecorator('v_entry')(<RangePicker style={{ width: '220px' }} />)}
                </Search.Item>

                <Search.Item label="离职日期">
                    {getFieldDecorator('v_resign')(<RangePicker style={{ width: '220px' }} />)}
                </Search.Item>

                <Search.Item label="组织机构">
                    {getFieldDecorator(
                        'department',
                        {}
                    )(
                        <OrganizationSelect
                            isFunctional
                            extraQuery={{ auditStatus: 2 }}
                            dropdownStyle={{ maxHeight: 350, width: 298, overflow: 'auto' }}
                        />
                    )}
                </Search.Item>

                <Search.Item label="状态">
                    {getFieldDecorator('employeeStatus', { initialValue: jobStatusEnumList[0].value })(
                        <Select style={{ width: '12.875em' }}>
                            {jobStatusEnumList.map(status => (
                                <Option key={status.value} value={status.value}>
                                    {jobStatusEnum.getShowName(status.value)}
                                </Option>
                            ))}
                        </Select>
                    )}
                </Search.Item>
            </Search.More>
        </Search.Wrapper>
    );
};

const TableWrapper = ({ columns, dataSource, tablePageChange, pagination }) => (
    <div>
        <Table
            tableLayout="fixed"
            columns={columns}
            rowKey="employeeNo"
            dataSource={dataSource}
            pagination={false}
            scroll={{ x: 'max-content' }}
            bordered
        />
        <Pagination {...pagination} onChange={tablePageChange} />
    </div>
);

const InsuranceHousingFund = ({ selectOrganizationCode, dispatch, organizationResponse }) => {
    const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });
    const [dataSource, setDataSource] = useState([]);
    const [loading, setLoading] = useState(false);
    const [searchModel, setSearchModel] = useState({});
    const formRef = useRef();

    // 获取查询条件
    const getSearchCondition = useCallback(
        () => ({
            searchModel,
            pagination: pagination || {
                current: 1,
                pageSize: 10
            }
        }),
        [pagination, searchModel]
    );

    const getPostData = searchCondition => {
        const { current: pageNo, pageSize } = searchCondition.pagination;

        const page = { pageNo, pageSize };
        const { v_employeeCode, v_entry, v_resign, ...postModel } = searchCondition.searchModel;

        postModel.employeeCodes = v_employeeCode ? [v_employeeCode] : null;

        postModel.entryStart = v_entry?.[0]?.startOf('day')?.format('YYYY-MM-DD HH:mm:ss');
        postModel.entryEnd = v_entry?.[1]?.endOf('day')?.format('YYYY-MM-DD HH:mm:ss');

        postModel.resignStart = v_resign?.[0]?.startOf('day')?.format('YYYY-MM-DD HH:mm:ss');
        postModel.resignEnd = v_resign?.[1]?.endOf('day')?.format('YYYY-MM-DD HH:mm:ss');

        return { ...page, ...postModel, organizationCode: selectOrganizationCode };
    };

    // 查询
    const search = useCallback(pageInfo => {
        const searchCondition = getSearchCondition();
        if (pageInfo) {
            searchCondition.pagination = { ...searchCondition.pagination, ...omitBy(pageInfo, isNil) };
        } else {
            searchCondition.pagination.current = 1;
        }
        setLoading(true);
        insuranceHousingFundService
            .queryInsuranceHousingFund(getPostData(searchCondition))
            .then(searchResponse => {
                setLoading(false);
                if (isSuccess(searchResponse)) {
                    const { size: pageSize, total, current, records: dataSourceList } = searchResponse.data;
                    setDataSource(dataSourceList);
                    setPagination({
                        ...pagination,
                        pageSize: pageSize || 10,
                        current: current || 1,
                        total
                    });
                } else {
                    message.error(searchResponse.msg);
                }
            })
            .catch(() => {
                setLoading(false);
            });
    });

    // 页码变化
    const tablePageChange = useCallback(
        ({ current, pageSize }) => {
            search({
                current,
                pageSize
            });
        },
        [pagination]
    );

    useEffect(() => {
        // search();
    }, [searchModel]);

    useEffect(() => {
        if (selectOrganizationCode) {
            if (formRef.current) {
                // 重置表单数据并更新model
                formRef.current.resetFields();
                setSearchModel(formRef.current.getFieldsValue());
            }
            search();
        }
    }, [selectOrganizationCode]);

    const EnhancedSearchWrapper = useMemo(
        () =>
            Form.create({
                onValuesChange: (props, changedValues, allValues) => {
                    setSearchModel(allValues);
                }
            })(SearchWrapper),
        []
    );

    const handleOrganizationChange = useCallback(
        value => {
            if (selectOrganizationCode !== value) {
                dispatch({
                    type: `${namespace}/setMultiStore`,
                    payload: {
                        selectOrganizationCode: value,
                        countryNameCode: null
                    }
                });
            }
        },
        [selectOrganizationCode]
    );

    return (
        <PageHeaderWrapper type="success">
            <BaseSettingProvider organizationCode={selectOrganizationCode}>
                <InsuranceFundFileMenuFilter>
                    <InsuranceFundFileRouter
                        type="insuranceFundFile"
                        extraButton={
                            <div style={{ display: 'flex' }}>
                                <OrganizationSelect
                                    isStrictly
                                    isNeedPermission
                                    style={{ width: 220 }}
                                    onChange={handleOrganizationChange}
                                    value={selectOrganizationCode}
                                    allowClear={false}
                                    dropdownMatchSelectWidth
                                    treeDataFromProp
                                    treeDataList={organizationResponse}
                                />
                            </div>
                        }
                    >
                        <SalaryConfigTipPage organizationCode={selectOrganizationCode}>
                            <div className={salaryStyle.salaryWrapper}>
                                <Spin spinning={loading}>
                                    <EnhancedSearchWrapper
                                        onSearch={search}
                                        organizationCode={selectOrganizationCode}
                                        wrapperFormRef={form => {
                                            formRef.current = form;
                                        }}
                                    />
                                    <TableWrapper
                                        columns={tableColumns}
                                        dataSource={dataSource}
                                        tablePageChange={tablePageChange}
                                        pagination={pagination}
                                    />
                                </Spin>
                            </div>
                        </SalaryConfigTipPage>
                    </InsuranceFundFileRouter>
                </InsuranceFundFileMenuFilter>
            </BaseSettingProvider>
        </PageHeaderWrapper>
    );
};

export default connect(({ insuranceFundFileModel }) => ({
    selectOrganizationCode: insuranceFundFileModel.selectOrganizationCode,
    organizationResponse: insuranceFundFileModel.organizationResponse
}))(InsuranceHousingFund);
